package seguridad;

import java.security.*;
import javax.crypto.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Publicas
{
    public static void main( String args[] )
    {
        String algorithm = "RSA";

        
        
        if( args.length == 1 )
        {
            algorithm = args[ 0 ];
        }

        try
        {
            // Generar las llaves
            KeyPairGenerator generator = KeyPairGenerator.getInstance( algorithm );
            generator.initialize( 1024 );
            KeyPair keyPair = generator.generateKeyPair( );
            
           // cifrarArchivo(keyPair, "./data/pruebaCifrado.txt");
            
           // descifrarArchivo(keyPair, "./data/pruebaCifrado.txt");
            
            // Iniciar un objeto para la encr / desencr
            Cipher desCipher = Cipher.getInstance( "RSA" );
            // Leer, escribir y encriptar un dato
            BufferedReader stdIn = new BufferedReader( new InputStreamReader( System.in ) );
            String pwd = stdIn.readLine( );
            byte[] cleartext = pwd.getBytes( );
            String s1 = new String( cleartext );
            System.out.println( "password original:" + s1 );
            desCipher.init( Cipher.ENCRYPT_MODE, keyPair.getPublic( ) );
            byte[] ciphertext = desCipher.doFinal( cleartext );
            String s2 = new String( ciphertext );
            System.out.println( "password encriptado:" + s2 );
            // Ahora desencriptar
            desCipher.init( Cipher.DECRYPT_MODE, keyPair.getPrivate( ) );
            byte[] cleartext1 = desCipher.doFinal( ciphertext );
            String s3 = new String( cleartext1 );
            System.out.println( "password desencriptado:" + s3 );
        }
        catch( java.security.NoSuchAlgorithmException e1 )
        {
            e1.printStackTrace( );
        }
        catch( java.security.InvalidKeyException e2 )
        {
            e2.printStackTrace( );
        }
        catch( IllegalBlockSizeException e3 )
        {
            e3.printStackTrace( );
        }
        catch( javax.crypto.NoSuchPaddingException e4 )
        {
            e4.printStackTrace( );
        }
        catch( javax.crypto.BadPaddingException e5 )
        {
            e5.printStackTrace( );
        }
        catch( Exception e )
        {
            e.printStackTrace( );
        }
    }
    /**
     * cifra el archivo ingresado por parametro con la llave privada del key pair
     * @param kp 
     */
    public static void cifrarArchivo(KeyPair kp, String rutaArchivo)
    {
        BufferedReader in = null;
        try {
            File archivoCifrar = new File(rutaArchivo);
            System.out.println(archivoCifrar.getAbsolutePath());
            in = new BufferedReader( new InputStreamReader( new FileInputStream(archivoCifrar)) );
            
            String texto = "";
            String lineaNueva = in.readLine();
            while(lineaNueva!=null){
                texto+= lineaNueva;
                lineaNueva=in.readLine();
            }
            byte[] cleartext = texto.getBytes( );
                       
            // Iniciar un objeto para la encr / desencr
            Cipher desCipher = Cipher.getInstance( "RSA" );
            
            String textoClaro = new String( cleartext );
            System.out.println( "texto original:" + textoClaro );
            desCipher.init( Cipher.ENCRYPT_MODE, kp.getPublic( ) );
            byte[] ciphertext = desCipher.doFinal( cleartext );
            
            String textoCifrado = new String( ciphertext );
            System.out.println( "texto cifrado:" + textoCifrado );
           
            // borra el archivo  claro
            archivoCifrar.delete();
            
            // ahora reescribe el archivo para que quede cifrado
           PrintWriter pw = new PrintWriter(archivoCifrar);
           pw.print(textoCifrado);
           pw.close();
            
        } catch (Exception ex) {
            Logger.getLogger(Publicas.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                in.close();
            } catch (IOException ex) {
                Logger.getLogger(Publicas.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    
    
     public static void descifrarArchivo(KeyPair kp, String rutaArchivo)
    {
        BufferedReader in = null;
        try {
            File archivoDesCifrar = new File(rutaArchivo);
            in = new BufferedReader( new InputStreamReader( new FileInputStream(archivoDesCifrar)) );
            
            String texto = "";
            String lineaNueva = in.readLine();
            while(lineaNueva!=null){
                texto+= lineaNueva;
                lineaNueva=in.readLine();
            }
            
            byte[] ciphertext = texto.getBytes( );
            
            // Iniciar un objeto para la encr / desencr
            Cipher desCipher = Cipher.getInstance( "RSA" );
             String textoCifrado = new String( ciphertext );
             System.out.println("Texo Cifrado: "+textoCifrado);
            desCipher.init( Cipher.DECRYPT_MODE, kp.getPrivate( ) );
            
            byte[] cleartext1 = desCipher.doFinal( ciphertext );
            String textoClaro = new String( cleartext1 );
            System.out.println("Texo Claro: "+textoClaro);
            
            // borra el archivo cifrado
            archivoDesCifrar.delete();
            
            // ahora reescribe el archivo para que quede descifrado
           PrintWriter pw = new PrintWriter(archivoDesCifrar);
           pw.print(textoClaro);
           
           pw.close();
           
        } catch (Exception ex) {
            Logger.getLogger(Publicas.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
}